package no.mehdi.game.service;

import java.util.Random;

import no.mehdi.game.domain.GameResult;

/**
 * Generate the game result.
 * 
 * @author Mehdi Zare
 * 
 */
public class GameResultGenerator {
	/** Chance to win in percent */
	private final int CHANCE_TO_WIN;
	/** Chance to loss in percent */
	private final int CHANCE_TO_LOSE;
	/** Chance to draw in percent */
	private final int CHANCE_TO_DRAW;
	/** The lowest number in the range */
	private final static int LOWEST_RANGE = 0;
	/** The highest number in the range */
	private final static int HIGHEST_RANGE = 100;
	/** An instance of {@link Random} */
	private Random random;

	/**
	 * Constructor to make an instance of the class by spring
	 * 
	 * @param chanceToWin
	 *            the chance to win in percent.
	 * @param chanceToLoss
	 *            the chance to loss in percent.
	 * @param chanceToDraw
	 *            the chance to draw in percent.
	 */
	public GameResultGenerator(int chanceToWin, int chanceToLoss, int chanceToDraw) {
		super();
		CHANCE_TO_WIN = chanceToWin;
		CHANCE_TO_LOSE = chanceToLoss;
		CHANCE_TO_DRAW = chanceToDraw;
		random = new Random();
	}

	/**
	 * Generate the game result by taking a random number from 1-100. If the
	 * chances to win is 35% the the number between 1-35 are winners.
	 * 
	 * @return {@link GameResult}
	 */
	public GameResult generateResult() {
		// Set the cursor to lowest number in the range.
		int cursor = LOWEST_RANGE;
		int chanseToWinRange = cursor + CHANCE_TO_WIN;
		// Move the cursor the next range which is the chance of losing
		cursor = chanseToWinRange;
		int chanseToLoseRange = cursor + CHANCE_TO_LOSE;
		// Move the cursor the next range which is the chance of draw
		cursor = chanseToLoseRange;
		int chanseToDrawRange = cursor + CHANCE_TO_DRAW;
		// Choose a number randomly between 1-100.
		int result = random.nextInt(100) + 1;

		// Check the generated number to find which range it is.
		if (0 < result && result <= chanseToWinRange) {
			return GameResult.WIN;
		}
		if (chanseToWinRange < result && result <= chanseToLoseRange) {
			return GameResult.LOSE;
		}
		if (chanseToLoseRange < result && result <= chanseToDrawRange) {
			return GameResult.DRAW;
		}
		// This should never happen.
		throw new IllegalStateException("This should never happen. Somthing is realy wrong!");
	}

	/**
	 * Check the percents from configuration file to find out the sum of them is
	 * 100
	 */
	public void init() {
		if (!(CHANCE_TO_WIN + CHANCE_TO_LOSE + CHANCE_TO_DRAW == HIGHEST_RANGE)) {
			throw new IllegalArgumentException("Invalid game values the sum of all values should be " + HIGHEST_RANGE
					+ ". check the configuration file");
		}
	}

}
